package com.speedchina.common.upload.utils;

import com.alibaba.excel.converters.AutoConverter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.CellData;
import com.speedchina.common.domain.ConversionErrorResult;
import com.speedchina.common.domain.ConversionResults;
import com.speedchina.common.domain.ExcelReadResult;
import com.speedchina.common.download.base.CSVConfiguration;
import com.speedchina.common.download.utils.CsvWriter;
import com.speedchina.common.exception.ConverterException;
import com.speedchina.common.upload.annotation.Unique;
import com.speedchina.framework.exception.BException;
import com.speedchina.framework.utils.ReflectionUtils;
import com.speedchina.framework.validator.ValidatorHelper;
import com.speedchina.framework.validator.group.AddGroup;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 对list进行导入转换和校验
 * @author ZhangWC
 * @date 2021/6/29
 */
public class ListDataConverterUtils {
    /**
     * 工具类构造私有化
     */
    private ListDataConverterUtils(){}

    /**
     * list转换成能入库的数据，并进行校验，记录错误信息
     * author: ZhangWC
     * date: 2021/6/29
     * [list, clazz]
     * @return com.speedchina.common.domain.ConversionResults
     */
    public static ConversionResults listConverterCheck3(List list, Class clazz){
        //获取到实体的配置信息
        List<CSVConfiguration> csvConfigurationList = CsvWriter.getCSVConfiguration(clazz);
        List<ConversionErrorResult> errorResult = new ArrayList<>();
        ConcurrentHashMap<String, HashSet<Object>> repeatMap = new ConcurrentHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            //获取当前行
            Object obj = list.get(i);
            if (null != csvConfigurationList && 0 < list.size()) {
                for (CSVConfiguration csvConfiguration : csvConfigurationList) {
                    Converter converter = csvConfiguration.getConverter();
                    //转换字符
                    if (!AutoConverter.class.isInstance(converter)) {
                        //获取到当前的值
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        try {
                            //转换后的值重新赋值
                            fieldValue = converter.convertToJavaData(new CellData(fieldValue),null,null);
                        }catch (ConverterException e){
                            //出现异常，记录异常信息
                            ConversionErrorResult conversionErrorResult = new ConversionErrorResult(csvConfiguration.getHead(), i + 2L, e.getExceptionMsg());
                            errorResult.add(conversionErrorResult);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //重新设置当前属性的值为转换后的值
                        ReflectionUtils.setFieldValue(obj,csvConfiguration.getField().getName(),fieldValue);
                    }
                    //属性去重校验，可以利用Set集合的不可重复
                    if (csvConfiguration.getField().isAnnotationPresent(Unique.class)) {
                        HashSet<Object> setKey = repeatMap.get(csvConfiguration.getField().getName());
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        if (setKey != null) {
                            boolean addResult = setKey.add(fieldValue);
                            if (false == addResult) {
                                ConversionErrorResult conversionErrorResult = new ConversionErrorResult(csvConfiguration.getHead(), i + 2L, "此列值不能重复！");
                                errorResult.add(conversionErrorResult);
                            }
                        }else {
                            setKey = new HashSet<>();
                            setKey.add(fieldValue);
                            repeatMap.put(csvConfiguration.getField().getName(),setKey);
                        }
                    }
                }
            }
            try {
                //新增校验
                ValidatorHelper.validateEntity(obj, AddGroup.class);
            }catch (BException e){
                //错误信息添加
                String errMsg = e.getMessage();
                if(errMsg != null){
                    errMsg = errMsg.replaceAll("<br/>", "、");
                }
                ConversionErrorResult conversionErrorResult = new ConversionErrorResult(null, i + 2L, errMsg);
                errorResult.add(conversionErrorResult);
            }
        }
        return new ConversionResults(list,errorResult);
    }

    /**
     * list转换成能入库的数据，并进行校验，出现错误直接报出异常
     * author: ZhangWC
     * date: 2021/6/29
     * [list, clazz]
     * @return com.speedchina.common.domain.ConversionResults
     */
    public static List listConverterCheck2(List list, Class clazz) throws Exception {
        //获取到实体的配置信息
        List<CSVConfiguration> csvConfigurationList = CsvWriter.getCSVConfiguration(clazz);
        List<ConversionErrorResult> errorResult = new ArrayList<>();
        ConcurrentHashMap<String, HashSet<Object>> repeatMap = new ConcurrentHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            //获取当前行
            Object obj = list.get(i);
            if (null != csvConfigurationList && 0 < list.size()) {
                for (CSVConfiguration csvConfiguration : csvConfigurationList) {
                    Converter converter = csvConfiguration.getConverter();
                    //转换字符
                    if (!AutoConverter.class.isInstance(converter)) {
                        //获取到当前的值
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        //转换后的值重新赋值
                        fieldValue = converter.convertToJavaData(new CellData(fieldValue),null,null);

                        //重新设置当前属性的值为转换后的值
                        ReflectionUtils.setFieldValue(obj,csvConfiguration.getField().getName(),fieldValue);
                    }
                    //属性去重校验，可以利用Set集合的不可重复
                    if (csvConfiguration.getField().isAnnotationPresent(Unique.class)) {
                        HashSet<Object> setKey = repeatMap.get(csvConfiguration.getField().getName());
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        if (setKey != null) {
                            boolean addResult = setKey.add(fieldValue);
                            if (false == addResult) {
                                ConversionErrorResult conversionErrorResult = new ConversionErrorResult(csvConfiguration.getHead(), i + 2L, "此列值不能重复！");
                                errorResult.add(conversionErrorResult);
                            }
                        }else {
                            setKey = new HashSet<>();
                            setKey.add(fieldValue);
                            repeatMap.put(csvConfiguration.getField().getName(),setKey);
                        }
                    }
                }
            }
            //新增校验
            ValidatorHelper.validateEntity(obj, AddGroup.class);
        }
        return list;
    }

    /**
     * list转换成能入库的数据，并进行校验，记录错误信息
     * author: ZhangWC
     * date: 2021/6/29
     * [list, clazz]
     * @return com.speedchina.common.domain.ConversionResults
     */
    public static ConversionResults listConverterCheck(List<ExcelReadResult> list, Class clazz){
        //获取到实体的配置信息
        List<CSVConfiguration> csvConfigurationList = CsvWriter.getCSVConfiguration(clazz);
        List<ConversionErrorResult> errorResult = new ArrayList<>();
        ArrayList<Object> dataList = new ArrayList<>();
        ConcurrentHashMap<String, HashSet<Object>> repeatMap = new ConcurrentHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            //获取当前行
            ExcelReadResult excelReadResult = list.get(i);
            Object obj = excelReadResult.getPo();
            if (null != csvConfigurationList && 0 < list.size()) {
                for (CSVConfiguration csvConfiguration : csvConfigurationList) {
                    Converter converter = csvConfiguration.getConverter();
                    //转换字符
                    if (!AutoConverter.class.isInstance(converter)) {
                        //获取到当前的值
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        try {
                            //转换后的值重新赋值
                            fieldValue = converter.convertToJavaData(new CellData(fieldValue),null,null);
                        }catch (ConverterException e){
                            //出现异常，记录异常信息
                            ConversionErrorResult conversionErrorResult = new ConversionErrorResult(csvConfiguration.getHead(), excelReadResult.getRowIndex().longValue(), e.getExceptionMsg());
                            errorResult.add(conversionErrorResult);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //重新设置当前属性的值为转换后的值
                        ReflectionUtils.setFieldValue(obj,csvConfiguration.getField().getName(),fieldValue);
                    }
                    //属性去重校验，可以利用Set集合的不可重复
                    if (csvConfiguration.getField().isAnnotationPresent(Unique.class)) {
                        HashSet<Object> setKey = repeatMap.get(csvConfiguration.getField().getName());
                        Object fieldValue = ReflectionUtils.getFieldValue(obj, csvConfiguration.getField().getName());
                        if (setKey != null) {
                            boolean addResult = setKey.add(fieldValue);
                            if (false == addResult) {
                                ConversionErrorResult conversionErrorResult = new ConversionErrorResult(csvConfiguration.getHead(), excelReadResult.getRowIndex().longValue(), "此列值不能重复！");
                                errorResult.add(conversionErrorResult);
                            }
                        }else {
                            setKey = new HashSet<>();
                            setKey.add(fieldValue);
                            repeatMap.put(csvConfiguration.getField().getName(),setKey);
                        }
                    }
                }
            }
            try {
                //新增校验
                ValidatorHelper.validateEntity(obj, AddGroup.class);
            }catch (BException e){
                //错误信息添加
                String errMsg = e.getMessage();
                if(errMsg != null){
                    errMsg = errMsg.replaceAll("<br/>", "、");
                }
                ConversionErrorResult conversionErrorResult = new ConversionErrorResult(null, excelReadResult.getRowIndex().longValue(), errMsg);
                errorResult.add(conversionErrorResult);
            }
            dataList.add(obj);
        }
        return new ConversionResults(dataList,errorResult);
    }


}
